//
// Created by dddgzc on 2025/1/26.
//

#include "Player.h"
#include "algorithm"

Player::Player() {
    // 默认当前动画朝向右
    currentAnimation = &animationIdleRight;

    // 普通攻击cd时间定时器
    timerAttackCd.setWaitTime(attackCd);
    timerAttackCd.setIsOneShot(true); // 单次触发
    timerAttackCd.setCallback([&]() {
        canAttack = true;
    });

    // 初始化无敌状态定时器
    invulnerableTimer.setWaitTime(750);
    invulnerableTimer.setIsOneShot(true);
    invulnerableTimer.setCallback([&]() {
        isInvulnerable = false;
    });
    // 初始化无敌状态闪烁定时器
    invulnerableBlinkTimer.setWaitTime(75);
    invulnerableBlinkTimer.setCallback([&]() {
        isShowingSketchFrame = !isShowingSketchFrame; // 翻转闪烁状态
    });
    // 初始化粒子系统发射定时器
    timerRunEffectGeneration.setWaitTime(75);
    timerRunEffectGeneration.setCallback([&]() {
        Vector2 particlePosition;
        SDL_Texture *texture = runEffectAtlas->getImage(0);
        int width, height;
        SDL_QueryTexture(texture, NULL, NULL, &width, &height);
        particlePosition.x = position.x + (this->width - width) / 2;
        particlePosition.y = position.y + this->height - height;
        particles.emplace_back(particlePosition, runEffectAtlas, 45);
    });

    timerDieEffectGeneration.setWaitTime(35);
    timerDieEffectGeneration.setCallback([&]() {
        Vector2 particlePosition;
        SDL_Texture *texture = runEffectAtlas->getImage(0);
        int width, height;
        SDL_QueryTexture(texture, NULL, NULL, &width, &height);
        particlePosition.x = position.x + (this->width - width) / 2;
        particlePosition.y = position.y + this->height - height;
        particles.emplace_back(particlePosition, runEffectAtlas, 150);
    });
    // 设置跳跃粒子
    jumpEffectAnimation.setAtlas(jumpEffectAtlas);
    jumpEffectAnimation.setInterval(45);
    jumpEffectAnimation.setIsLoop(false);
    jumpEffectAnimation.setOnAnimationFinishedCallback([&]() {
        isJumpEffectValid = false;
    });
    // 设置跳跃落地粒子
    landEffectAnimation.setAtlas(landEffectAtlas);
    landEffectAnimation.setInterval(45);
    landEffectAnimation.setIsLoop(false);
    landEffectAnimation.setOnAnimationFinishedCallback([&]() {
        isLandEffectValid = false;
    });
}

void Player::setPosition(int x, int y) {
    this->position.x = x;
    this->position.y = y;
}

// 移动和碰撞检测
void Player::moveAndCollide(int delta) {
    // 上一帧的速度
    float lastFrameVelocity = this->velocity.y;

    this->velocity.y += gravity * delta;
    this->position += this->velocity * delta;

    if (hp <= 0) return;

    if (this->velocity.y > 0) {
        // y方向的速度大于0 说明是在下落状态
        for (int i = 0; i < platforms.size(); i++) {
            bool isCollisionX = std::max(position.x + width, (float) platforms[i]->collisionShape.right) - std::min(
                                    position.x, (float) platforms[i]->collisionShape.left)
                                <= width + (platforms[i]->collisionShape.right - platforms[i]->collisionShape.left);
            // x轴的判断有问题
            bool isCollisionY = (platforms[i]->collisionShape.y >= position.y && platforms[i]->collisionShape.y <=
                                 position.y + height);
            if (isCollisionX && isCollisionY) {
                // SDL_Log("position.x = %f; collisionShape.left:%f; collisionShape.right:%f", position.x,
                //         platforms[i]->collisionShape.left, platforms[i]->collisionShape.right);
                position.y = platforms[i]->collisionShape.y - height;
                velocity.y = 0;

                // 当当前和平台发生了碰撞且 碰撞上一帧的速度不为0（说明是在运动状态中） 则启动落地的粒子动画）
                if (lastFrameVelocity != 0) {
                    onLand();
                }
                break;
            }
        }
    }

    // 子弹逻辑处理
    if (!isInvulnerable) {
        for (int i = 0; i < bullets.size(); i++) {
            if (!bullets[i]->getValid() || bullets[i]->getCollideTarget() != playerID) {
                continue;
            }
            if (bullets[i]->checkCollision(position, getSize())) {
                makeInvulnerable();
                bullets[i]->setValid(false);
                bullets[i]->onCollide();
                hp -= bullets[i]->getDamage();
                lastHartPosition.x = position.x - bullets[i]->getPosition().x;
                if (hp <= 0) {
                    // 给玩家一个抛起的速度值
                    this->velocity.x = lastHartPosition.x < 0 ? -0.35f : 0.35f;
                    this->velocity.y = -1.0f;
                }
            }
        }
    }
}

void Player::onJump() {
    if (this->velocity.y != 0 || isAttackingEx) // y方向的不等于0时，不执行跳跃
        return;
    this->velocity.y += jump_velocity;
    this->isJumpEffectValid = true;
    this->jumpEffectAnimation.reset();
    // 计算跳跃粒子动画的播放位置
    int jumpEffectWidth, jumpEffectHeight;
    SDL_QueryTexture(jumpEffectAnimation.getFrame(), NULL, NULL, &jumpEffectWidth, &jumpEffectHeight);
    this->jumpEffectPosition.x = this->position.x + (this->width - jumpEffectWidth) / 2;
    this->jumpEffectPosition.y = this->position.y + (this->height - jumpEffectHeight);

}

void Player::onLand() {
    isLandEffectValid = true;
    landEffectAnimation.reset();
    // 计算落地粒子动画的播放位置
    int landEffectWidth, landEffectHeight;
    SDL_QueryTexture(landEffectAnimation.getFrame(), NULL, NULL, &landEffectWidth, &landEffectHeight);
    this->landEffectPosition.x = this->position.x + (this->width - landEffectWidth) / 2;
    this->landEffectPosition.y = this->position.y + (this->height - landEffectHeight);
}

int Player::getHp() {
    return this->hp;
}

int Player::getMp() {
    return this->mp;
}

void Player::setHp(int hp) {
    this->hp = hp;
}

Vector2 Player::getPosition() {
    return this->position;
}

Vector2 Player::getSize() {
    return {(float) width, (float) height};
}

void Player::onAttack() {
}

void Player::onAttackEx() {
}

void Player::makeInvulnerable() {
    isInvulnerable = true;
    invulnerableTimer.resetTime();
}


void Player::onDraw(const Camera &camera) {
    for (int i = 0; i < particles.size(); i++) {
        particles[i].onDraw(camera);
    }

    if (isJumpEffectValid) {
        jumpEffectAnimation.onDraw(camera, jumpEffectPosition.x, jumpEffectPosition.y);
    }

    if (isLandEffectValid) {
        landEffectAnimation.onDraw(camera, landEffectPosition.x, landEffectPosition.y);
    }

    if (hp <= 0) {

    }

    if (hp > 0 && isInvulnerable && isShowingSketchFrame) {
        SDL_SetTextureColorMod(currentAnimation->getFrame(), 254, 0, 0);
        draw(camera, currentAnimation->getFrame(), position.x, position.y);
    } else {
        SDL_SetTextureColorMod(currentAnimation->getFrame(), 255, 255, 255);
        currentAnimation->onDraw(camera, position.x, position.y);
    }

    if (IS_DEBUG_MODE) {
        // 调试模式 绘制一个框
        drawRectangle(camera, position.x, position.y, width, height, {255, 0, 0, 255});
    }
}

void Player::onUpdate(int delta) {
    if (isRightKeyDown) {
        if (isAttackingEx) return; // 如果在释放技能过程中 不能移动
        isFacingRight = true;
        currentAnimation = &animationRunRight;
        this->position.x += this->run_velocity * delta; // 控制移动
        timerRunEffectGeneration.resume();
    } else if (isLeftKeyDown) {
        if (isAttackingEx) return; // 如果在释放技能过程中 不能移动
        isFacingRight = false;
        currentAnimation = &animationRunLeft;
        this->position.x -= this->run_velocity * delta; // 控制移动
        timerRunEffectGeneration.resume();
    } else {
        currentAnimation = isFacingRight ? &animationIdleRight : &animationIdleLeft;
        timerRunEffectGeneration.pause();
    }

    if (isAttackingEx) {
        // 如果是在攻击状态下 则显示攻击状态下的动画
        currentAnimation = isFacingRight ? &animationAttackExRight : &animationAttackExLeft;
    }

    if (hp <= 0) {
        // 角色死亡
        currentAnimation = isFacingRight ? &animationDieRight : &animationDieLeft;
    }

    currentAnimation->onUpdate(delta);
    timerAttackCd.onUpdate(delta);
    invulnerableTimer.onUpdate(delta);
    invulnerableBlinkTimer.onUpdate(delta);
    timerRunEffectGeneration.onUpdate(delta);
    jumpEffectAnimation.onUpdate(delta);
    landEffectAnimation.onUpdate(delta);

    if (hp <= 0) {
        timerDieEffectGeneration.onUpdate(delta);
    }

    // 删除失效的粒子
    auto end = std::remove_if(particles.begin(), particles.end(), [](const Particle p) {
        return !p.checkValid();
    });
    particles.erase(end, particles.end());
    // 更新粒子
    for (int i = 0; i < particles.size(); i++) {
        particles[i].onUpdate(delta);
    }

    moveAndCollide(delta);
}

void Player::onInput(const SDL_Event &event) {
    // 按键按下
    switch (event.type) {
        case SDL_KEYDOWN:
            // 按键按下事件
            if (playerID == PlayerID::PLAYER_1) {
                switch (event.key.keysym.sym) {
                    case SDLK_a:
                        isLeftKeyDown = true;
                        break;
                    case SDLK_d:
                        isRightKeyDown = true;
                        break;
                    case SDLK_w:
                        onJump();
                        break;
                    case SDLK_f:
                        // 攻击键按下
                        if (canAttack) {
                            onAttack();
                            canAttack = false;
                            timerAttackCd.resetTime();
                        }
                        break;
                    case SDLK_g:
                        if (this->mp >= 100) {
                            onAttackEx();
                            this->mp = 0;
                        }
                        break;
                    default:
                        break;
                }
            } else if (playerID == PlayerID::PLAYER_2) {
                switch (event.key.keysym.sym) {
                    case SDLK_LEFT:
                        isLeftKeyDown = true;
                        break;
                    case SDLK_RIGHT:
                        isRightKeyDown = true;
                        break;
                    case SDLK_UP:
                        onJump();
                        break;
                    case SDLK_l:
                        if (canAttack) {
                            onAttack();
                            canAttack = false;
                            timerAttackCd.resetTime();
                        }
                        break;
                    case SDLK_k:
                        if (this->mp >= 100) {
                            onAttackEx();
                            this->mp = 0;
                        }
                    default:
                        break;
                }
            }
            break;
        case SDL_KEYUP:
            // 按键抬起
            if (playerID == PlayerID::PLAYER_1) {
                switch (event.key.keysym.sym) {
                    case SDLK_a:
                        isLeftKeyDown = false;
                        break;
                    case SDLK_d:
                        isRightKeyDown = false;
                        break;
                    default:
                        break;
                }
            } else if (playerID == PlayerID::PLAYER_2) {
                switch (event.key.keysym.sym) {
                    case SDLK_LEFT:
                        isLeftKeyDown = false;
                        break;
                    case SDLK_RIGHT:
                        isRightKeyDown = false;
                        break;
                    default:
                        break;
                }
            }
            break;
        default:
            break;
    }
}


void Player::setPlayerID(PlayerID id) {
    this->playerID = id;
}
